<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>01_let关键字</title>
</head>
<body>

<button>测试1</button>
<br>
<button>测试2</button>
<br>
<button>测试3</button>
<br>
<!--
***let
1. 作用:
  * 与var类似, 用于声明一个变量
2. 特点:
  * 只在当前块级作用域内有效(类似于局部变量)
  * 在同一代码块内，不能重复声明
  * 不会预处理, 不存在变量提升
  * 暂时性死区:在代码块内，使用let命令声明变量之前，该变量都是不可用的(必须先声明后使用, 即不会被提升到作用域顶部)
3. 应用:
  * 循环遍历加监听
  * 使用let取代var是趋势
-->
<script>
	// var声明的变量可以重新赋值、重复定义,存在变量提升
	console.log(price)//undefined
	var price=100
	console.log(price)//100
	price=200
	console.log(price)//200
	var price=100
	console.log(price)//100

	var condition = true
	if (condition) {
		var value = 1;
	}
	console.log(value, window.value); // 1 
	// 如果 condition 为 false，结果会是 undefined

	for (var i = 0; i < 10; i++) {
	}
	console.log(i, window.i); // 10
	
	/*
		var声明的变量属于function scoped,
		即函数内部定义的变量外界不能访问,
		并且在没有函数的情况下,例如判断语句里面的变量是属于全局变量的 
		除此之外，在 for 循环中, i也是属于全局变量的
		并且使用var声明的变量,会提升到作用域顶部,即绑定到全局作用域window上
	*/
</script>
<script type="text/javascript">
	
		// 函数作用域(function scoped)
		// var count=10;
		// if(count>5){
		// 	var discount=price*0.6;
		// 	console.log('The discount is '+ discount);
		// 	/*
		// 		The discount is 60 
		// 		只希望discount是一个临时变量，然而外部却是可以访问的，说明discount是暴露在if语句之外的全局变量
		// 	*/
		// }
		// console.log(discount);//60 全局变量
		
		
		// 块级作用域(block scoped)
	    {
			var count=10;
			if(count>5){
				let discount=price*0.6;
				console.log('The discount is '+ discount);//The discount is 60 类似于局部变量
			}
			// let和const声明的变量必须在当前块级作用域中访问
			console.log(discount);// discount is not defined 
		}
</script>
<script>
	// 函数作用域(function scoped) vs 块级作用域(block scoped)
	{
		// 变量i是var声明的,在全局范围内都有效,所以全局只有一个变量i
		// 每一次循环,变量i的值都会发生改变,而循环内被赋值的i变量,里面的i指向的都是全局的i,所以导致运行时输出的是最后的一轮i的值
		for (var i = 0; i < 10; i++) {
			var i='函数作用域';
			console.log(i);//1次函数作用域
		}
		
		// 说明输出的i和循环的i不是同一个变量,它们只在自己的代码块内有效
		// 每次迭代循环时都创建一个新变量，并以之前迭代中同名变量的值将其初始化
		// 另外,for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域，而循环体内部是一个单独的子作用域。
		for (let i = 0; i < 10; i++) {
			let i='块级作用域';
			console.log(i);//10次块级作用域
		}
	}
</script>
<script>
	// 点击事件是回调函数,js解析器会将其放在事件队列里面,等主线程的代码执行完毕,再将回调函数通过钩子来执行
	var btns = document.getElementsByTagName('button');
	for(var i = 0;i<btns.length;i++){
		// 每次循环的时候都创建一个独立的作用域 => 使用let即可轻松解决，不需要再使用闭包实现
		(function(i){
			btns[i].onclick = function () {
				alert(i);
			}
		})(i);	
	}
</script>
</body>

</html>